<template>
	<view class="com-image" :class="{'y-flex': mode != 'widthFix'}">
		<image :lazy-load="lazyLoad" @load="handleLoad" @error="handleError"
		class="com-image-item com-image-transition" :src="url" :mode="mode"
		:style="[imageStyle]"></image>
		<view class="com-image-box com-image-transition y-flex y-align-center y-justify-center" :style="[imageBoxStyle]">
			<slot name="loading" v-if="loading">
				<text class="tip" :style="{color: tipColorSync, 'font-size': pixelunit(tipSize)}">加载中</text>
			</slot>
			<slot name="error" v-if="error">
				<text class="tip" :style="{color: tipColorSync,  'font-size': pixelunit(tipSize)}">加载失败</text>
			</slot>
		</view>
	</view>
</template>

<script>
	import SkinColor from '@/assets/skin/index.js'
	import { downloadImageSaveLocal } from '@/assets/js/util.js'
	export default {
		props: {
			//图片链接
			src: {
				type: String,
				default: ''
			},
			//裁剪模式
			mode: {
				type: String,
				default: ''
			},
			//懒加载
			lazyLoad: {
				type: Boolean,
				default: false
			},
			bgColor: {
				type: String,
				default: ''
			},
			//圆角大小
			borderRadius: {
				type: [Number,String],
				default: 0
			},
			borderTopLeftRadius: {
				type: [Number,String],
				default: 0
			},
			borderTopRightRadius: {
				type: [Number,String],
				default: 0
			},
			borderBottomRightRadius: {
				type: [Number,String],
				default: 0
			},
			borderBottomLeftRadius: {
				type: [Number,String],
				default: 0
			},
			tipSize: {
				type: [String, Number],
				default: 30
			},
			tipColor: {
				type: String,
				default: ''
			},
			referer: {
				type: String,
				default: ''
			}
		},
		computed: {
			skinMode () {
				return this.$store.getters['setting/GET_SKIN_MODE']
			},
			skinColor () {
				return SkinColor[this.skinMode]
			},
			tipColorSync () {
				return this.tipColor || this.skinColor.color_1
			},
			imageStyle () {
				return Object.assign({}, this.mode != 'aspectFit' ? this.borderRadiusStyle : {}, {
					'flex': this.mode != 'widthFix' ? 1 : 0,
					'opacity': (this.loading || this.error) ? 0 : 1
				}) 
			},
			imageBoxStyle () {
				return Object.assign({}, this.borderRadiusStyle, {
					'background-color': this.bgColor || this.skinColor.color_gap_1,
					'opacity': (this.loading || this.error) ? 1 : 0
				}) 
			},
			borderRadiusStyle () {
				return this.borderRadius > 0 ? {
					borderRadius: this.pixelunit(this.borderRadius),
				} : {
					borderTopLeftRadius: this.pixelunit(this.borderTopLeftRadius),
					borderTopRightRadius: this.pixelunit(this.borderTopRightRadius),
					borderBottomRightRadius: this.pixelunit(this.borderBottomRightRadius),
					borderBottomLeftRadius: this.pixelunit(this.borderBottomLeftRadius),
				}
			}
		},
		data() {
			return {
				url: '',
				loading: true,
				error: false,
				isReferer: false
			}
		},
		created() {
			this.url = this.src
		},
		methods: {
			handleLoad(e) {
				this.$emit('load', e)
				this.loading = false
			},
			handleError(e) {
				if ( !this.isReferer && this.src ) {
					this.isReferer = true
					this.loading = true
					downloadImageSaveLocal({
						src: this.src,
						referer: this.referer,
						complete: path => {
							this.url = path
							this.loading = false
						}
					})
				} else {
					this.error = true
					this.loading = false
					this.$emit('error', e);
				}
			},
			pixelunit (size) {
				const text = size.toString()
				return text.indexOf('px') > -1 ? text : text + 'rpx'
			}
		},
		watch: {
			src (newVal) {
				this.url = newVal
				this.loading = true
				this.isReferer = false
				this.error = false
			}
		}
	}
</script>

<style>
	.com-image {
		position: relative;
	}
	.com-image-box {
		position: absolute;
		top: 0;
		left: 0;
		right: 0;
		bottom: 0;
	}
	/* #ifndef APP-NVUE */
	.com-image-item {
		width: 100%;
		flex-shrink: 0;
	}
	/deep/ .com-image-item > div {
		position: absolute;
		top: 0;
		left: 0;
		right: 0;
		bottom: 0;
	}
	/* #endif */
	.com-image-transition {
		transition-property: opacity;
		transition-duration: 200ms;
	}
</style>
